package org.seven.jrdp.commons.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.net.ssl.SSLContext;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.seven.jrdp.commons.constant.GlobalContants;

public abstract class HttpUtils {
	private static String ENCODING = GlobalContants.ENCODING_UTF;

	public static String get(String url) {
		try {
			CloseableHttpClient http = HttpClients.createDefault();
			HttpGet get = new HttpGet(url);
			CloseableHttpResponse httpResponse = http.execute(get);
			HttpEntity responseEntity = httpResponse.getEntity();
			String result = EntityUtils.toString(responseEntity, ENCODING);
			EntityUtils.consume(responseEntity);
			httpResponse.close();
			http.close();
			return result;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static String post(String url, String entity) {
		try {
			CloseableHttpClient http = HttpClients.createDefault();
			HttpPost post = new HttpPost(url);
			post.setEntity(new StringEntity(entity, ENCODING));
			CloseableHttpResponse httpResponse = http.execute(post);
			HttpEntity responseEntity = httpResponse.getEntity();
			String result = EntityUtils.toString(responseEntity, ENCODING);
			EntityUtils.consume(responseEntity);
			httpResponse.close();
			http.close();
			return result;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static String post(String url, Map<String, String> params) {
		try {
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
			Set<String> keySet = params.keySet();
			for (String key : keySet) {
				nvps.add(new BasicNameValuePair(key, params.get(key)));
			}
			CloseableHttpClient http = HttpClients.createDefault();
			HttpPost post = new HttpPost(url);
			StringEntity entity = new StringEntity("Content-Type");
			entity.setContentType("text/plain;charset=UTF-8");
			post.setEntity(new UrlEncodedFormEntity(nvps));
			CloseableHttpResponse httpResponse = http.execute(post);
			HttpEntity responseEntity = httpResponse.getEntity();
			String result = EntityUtils.toString(responseEntity, ENCODING);
			EntityUtils.consume(responseEntity);
			httpResponse.close();
			http.close();
			return result;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static String post(String url, String entity, String cert, String password) {
		try {
			KeyStore keyStore = KeyStore.getInstance("PKCS12");
			InputStream in = new FileInputStream(new File(cert));
			keyStore.load(in, password.toCharArray());
			in.close();
			SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, password.toCharArray()).build();
			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
			CloseableHttpClient http = HttpClients.custom().setSSLSocketFactory(sslsf).build();
			HttpPost post = new HttpPost(url);
			post.setEntity(new StringEntity(entity, ENCODING));
			CloseableHttpResponse httpResponse = http.execute(post);
			HttpEntity responseEntity = httpResponse.getEntity();
			String result = EntityUtils.toString(responseEntity, ENCODING);
			EntityUtils.consume(responseEntity);
			httpResponse.close();
			http.close();
			return result;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static String post(String url, Map<String, String> params, String cert, String password) {
		try {
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
			Set<String> keySet = params.keySet();
			for (String key : keySet) {
				nvps.add(new BasicNameValuePair(key, params.get(key)));
			}
			KeyStore keyStore = KeyStore.getInstance("PKCS12");
			InputStream in = new FileInputStream(new File(cert));
			keyStore.load(in, password.toCharArray());
			in.close();
			SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, password.toCharArray()).build();
			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
			CloseableHttpClient http = HttpClients.custom().setSSLSocketFactory(sslsf).build();
			HttpPost post = new HttpPost(url);
			StringEntity entity = new StringEntity("Content-Type");
			entity.setContentType("text/plain;charset=UTF-8");
			post.setEntity(new UrlEncodedFormEntity(nvps));
			CloseableHttpResponse httpResponse = http.execute(post);
			HttpEntity responseEntity = httpResponse.getEntity();
			String result = EntityUtils.toString(responseEntity, ENCODING);
			EntityUtils.consume(responseEntity);
			httpResponse.close();
			http.close();
			return result;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static void saveHtml(String path, File file) {
		try {
			String html = getHtml(path);
			FileUtils.touch(file);
			FileUtils.writeStringToFile(file, html, ENCODING);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static String getHtml(String path) {
		try {
			StringWriter out = new StringWriter();
			URL url = new URL(path);
			URLConnection conn = url.openConnection();
			InputStream in = conn.getInputStream();
			IOUtils.copy(in, out, ENCODING);
			in.close();
			return out.toString();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}